package com.warmheart.base.aspect;


import com.warmheart.base.annotation.AddOperateLog;
import com.warmheart.base.session.SessionLocalUtils;
import com.warmheart.core.enums.OperationType;
import com.warmheart.core.result.CommonResult;
import com.warmheart.core.util.IpUtil;
import com.warmheart.core.util.OperatorUtil;
import com.warmheart.entity.operation.OperationLog;
import com.warmheart.entity.user.UserLogin;
import com.warmheart.impl.operation.OperationLogService;
import com.warmheart.impl.user.UserLoginService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 *
 * @ClassName: OperatorLogAspect
 * @Description: 操作日志记录
 * @author XuXiangyu
 * @date 2025-06-23 16:37:02
 *
 */
@Aspect
@Component
public class OperatorLogAspect {

    @Autowired(required = false)
    UserLoginService userLoginService;

    @Autowired(required = false)
    OperationLogService operationLogService;

    private static Logger logger = LoggerFactory.getLogger(OperatorLogAspect.class);

    @Pointcut("execution(* com.warmheart.controller..*Controller.*(..))&&@annotation(com.warmheart.base.annotation.AddOperateLog)")
    public void addOperatorLogPointcut() {}

    @Around("addOperatorLogPointcut()")
    public Object addOperatorLog(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info("开始记录操作日志");
        //获取类名
        String clsName = joinPoint.getTarget().getClass().getSimpleName();
        //获取方法名
        String methodName = joinPoint.getSignature().getName();
        //获取方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取方法上的注解
        AddOperateLog annotation = signature.getMethod().getAnnotation(AddOperateLog.class);
        //获取操作类型addLog是否为true
        boolean flag = annotation.addLog();
        //获取操作类型
        OperationType operationType = annotation.value();
        //获取被拦截方法参数-实体对象
        Object[] args = joinPoint.getArgs();
        Object entity = args[0];

        //获取当前用户userId
        Integer userId = SessionLocalUtils.getOperator().getLoginUser().getUserId();
        //获取用户名
        UserLogin userLogin = userLoginService.queryById(userId);
        String loginName = userLogin.getLoginName();
        //获取用户ip地址
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String ipAddress = IpUtil.getIpAddr(request);
        //获取请求url
        String url = request.getRemoteAddr();

        //创建操作日志对象，保存到数据库操作日志表中
        OperationLog operationLog = new OperationLog();
        operationLog.setUserId(userId);
        operationLog.setName(loginName);
        operationLog.setIpAddress(ipAddress);
        operationLog.setRequestUri(url);
        operationLog.setRequestMethod(methodName);
        //判断接口是否执行成功
        Object result;
        boolean success = false;
        result = joinPoint.proceed(); // 执行目标方法
        if (result instanceof CommonResult) {
            CommonResult<?> commonResult = (CommonResult<?>) result;

            // 判断成功/失败
            if (commonResult.getCode() == 200) {
                success = true;
            } else {
                success = false;
            }
        }
        if(success) {
            operationLog.setStatus("01");
        }
        else{
            operationLog.setStatus("02");
        }

        String description;
        if(operationType==OperationType.INSERT){
            if(success){
                description=loginName+"在"+clsName+"类上添加了一条数据，数据为"+entity;
            }
            else{
                description=loginName+"在"+clsName+"类上进行添加操作失败";
            }
            operationLog.setOperationDesc(description);
        }
        if (operationType==OperationType.DELETE){
            if(success){
                description=loginName+"在"+clsName+"类上删除了一条数据，数据为"+entity;
            }
            else{
                description=loginName+"在"+clsName+"类上进行删除操作失败";
            }
            operationLog.setOperationDesc(description);
        }
        if (operationType==OperationType.QUERY){
            if(success){
                description=loginName+"在"+clsName+"类上查找了一条数据，数据为"+entity;
            }
            else{
                description=loginName+"在"+clsName+"上进行查询操作失败";
            }
            operationLog.setOperationDesc(description);
        }
        if(operationType==OperationType.UPDATE){
            if(success){
                description=loginName+"在"+clsName+"类上更新了一条数据，数据为"+entity;
            }
            else{
                description=loginName+"在"+clsName+"类上进行更新操作失败";
            }
            operationLog.setOperationDesc(description);
        }
        if(flag){
            OperatorUtil.addOper(operationLog);
            operationLogService.add(operationLog);
        }
        return result;

    }
}
